package com.cictec.middleware.tde.rm.protocol;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.cictec.middleware.tde.rm.protocol.annotion.TerminalMessageDecoder;
import com.cictec.middleware.tde.rm.protocol.annotion.TerminalMessageEncoder;
import com.impetus.annovention.ClasspathDiscoverer;
import com.impetus.annovention.listener.ClassAnnotationDiscoveryListener;

/**
 * 注解扫描方式编解码器实现类，获取系统所有的编解码器
 * 
 * @author Administrator
 *
 */
@Component
public class AnnotationCodecFounder implements MessageCodecFounder {

	private static Logger logger = LoggerFactory.getLogger(AnnotationCodecFounder.class);

	private Map<Integer, MessageDecoder> decoders = new HashMap<Integer, MessageDecoder>();
	private Map<Integer, MessageEncoder> encoders = new HashMap<Integer, MessageEncoder>();

	public AnnotationCodecFounder() {
		logger.debug("【锐明协议】【加载指令编解码器】");
		loadDecoders();
	}

	public static void main(String[] args) {
		AnnotationCodecFounder df = new AnnotationCodecFounder();
		df.printAllDecoders();
		df.printAllEncoders();
	}

	@Override
	public MessageDecoder getDecoder(int messageId) {
		return decoders.get(messageId);
	}

	@Override
	public MessageEncoder getEncoder(int messageId) {
		return encoders.get(messageId);
	}

	/**
	 * 打印所有的解码器
	 */
	public void printAllDecoders() {
		for (Integer key : decoders.keySet()) {
			System.out.println(key + "   " + decoders.get(key).getClass().getName());
		}
	}
	/**
	 * 打印所有的解码器
	 */
	public void printAllEncoders() {
		for (Integer key : encoders.keySet()) {
			System.out.println(key + "   " + encoders.get(key).getClass().getName());
		}
	}

	/**
	 * 注册加载：加载通信协议编解码 处理类
	 * ，加载注解为【@TerminalMessageDecoder、@TerminalMessageEncoder】的编解码器
	 */
	private void loadDecoders() {

		ClasspathDiscoverer discoverer = new ClasspathDiscoverer();

		discoverer.addAnnotationListener(new DecoderAnnotationDiscoveryListener());
		discoverer.addAnnotationListener(new EncoderAnnotationDiscoveryListener());

		discoverer.discover(true, false, false, true, true);
	}

	/**
	 * 接口解码器扫描实现
	 * @author ql
	 *
	 */
	class DecoderAnnotationDiscoveryListener implements ClassAnnotationDiscoveryListener {

		@Override
		public void discovered(String clazz, String annotation) {

			try {
				Class<?> clz = Class.forName(clazz);
				int messageId = clz.getAnnotation(TerminalMessageDecoder.class).value();
				AbstractMessageDecoder md = (AbstractMessageDecoder) clz.newInstance();
				decoders.put(messageId, md);
			} catch (Exception e) {
				e.printStackTrace();
			}

			logger.info("Discovered Class(" + clazz + ") with Annotation(" + annotation + ")");
		}

		@Override
		public String[] supportedAnnotations() {
			return new String[] { TerminalMessageDecoder.class.getName() };
		}
	}

	/**
	 * 接口编码器扫描实现
	 * @author ql
	 *
	 */
	class EncoderAnnotationDiscoveryListener implements ClassAnnotationDiscoveryListener {

		@Override
		public void discovered(String clazz, String annotation) {

			try {
				Class<?> clz = Class.forName(clazz);
				int messageId = clz.getAnnotation(TerminalMessageEncoder.class).value();
				AbstractMessageEncoder md = (AbstractMessageEncoder) clz.newInstance();
				encoders.put(messageId, md);
			} catch (Exception e) {
				e.printStackTrace();
			}

			logger.info("Discovered Class(" + clazz + ") with Annotation(" + annotation + ")");
		}

		@Override
		public String[] supportedAnnotations() {
			return new String[] { TerminalMessageEncoder.class.getName() };
		}
	}

}
